package com.honeycomb.article.control;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.honeycomb.article.PageView;
import com.honeycomb.article.PositionScope;
import com.honeycomb.article.SearchPattern;
import com.honeycomb.article.dto.ArticleCatagory;
import com.honeycomb.article.dto.ArticleDetailMessageDto;
import com.honeycomb.article.dto.ArticleinfoDto;
import com.honeycomb.article.dto.Author;
import com.honeycomb.article.dto.ContentStatus;
import com.honeycomb.article.dto.MessageType;
import com.honeycomb.article.service.ArticleService;
import com.honeycomb.common.PositionInfo;
import com.honeycomb.common.ResourceManager;
import com.honeycomb.user.dto.UserinfoDto;
import com.honeycomb.user.dto.UserinfoDto.Sex;
import com.honeycomb.utils.MyDateDTTM;
import com.honeycomb.utils.SystemConstants;
import com.honeycomb.utils.SystemTools;

import static com.honeycomb.common.ParamConverter.*;

/**
 * 文章控制器
 * 
 * @author Wangyu
 */
@Controller
@RequestMapping("article/")
public class ArticleControl {

	protected Logger logger = LogManager.getLogger(this.getClass());

	@Resource
	private ArticleService articleService;

	@RequestMapping("ajaxSelectArticle")
	@ResponseBody
	public Map<String, Object> ajaxSelectArticle(HttpServletRequest request) {
		String articleCatagoryStr = assertNotEmpty(request.getParameter("articleCatagory"));
		String searchPatternStr = assertNotEmpty(request.getParameter("searchPattern"));
		String minXStr = assertNotEmpty(request.getParameter("minX"));
		String minYStr = assertNotEmpty(request.getParameter("minY"));
		String maxXStr = assertNotEmpty(request.getParameter("maxX"));
		String maxYStr = assertNotEmpty(request.getParameter("maxY"));
		
		String pageNumberStr = request.getParameter("pageNumber");
		String pgViewEncodeStr = request.getParameter("pgViewEncodeStr");
		
		if (logger.isDebugEnabled()) {
			logger.debug("ajaxSelectArticle entered, pageNumberStr=" + pageNumberStr + ", pgViewEncodeStr=" + pgViewEncodeStr + ", articleCatagory=" + articleCatagoryStr + ", searchPatternStr=" + searchPatternStr + ", minXStr=" + minXStr + ", minYStr=" + minYStr + ", maxXStr=" + maxXStr + ", maxYStr=" + maxYStr);
		}

		// create default pageView if no input
		PageView<ArticleinfoDto> pageView = isNullOrEmpty(pgViewEncodeStr) ? new PageView<ArticleinfoDto>(SystemConstants.PAGE_VIEW_DATA_COUNT_PER_PAGE_FOR_ARTICLE_LIST) : PageView.decode(pgViewEncodeStr);
		int pageNumber = isNullOrEmpty(pageNumberStr) ? pageView.getFirstPage() : convertToInteger(pageNumberStr);
				
		SearchPattern searchPattern = SearchPattern.getSearchPattern(searchPatternStr);
		ArticleCatagory catagory = ArticleCatagory.getArticleCatagory(articleCatagoryStr);
			
		double minX = convertToDouble(minXStr);
		double minY = convertToDouble(minYStr);
		double maxX = convertToDouble(maxXStr);
		double maxY = convertToDouble(maxYStr);
			
		pageView = articleService.searchArticles(catagory,
													searchPattern,
													new PositionScope(minX, minY, maxX, maxY),
													pageView);

		if (pageNumber > pageView.getLastPage() || pageNumber < pageView.getFirstPage()) {
			throw new IllegalArgumentException("Page " + pageNumber + " is not allowd for current view (" + pageView.getFirstPage() + "-" + pageView.getLastPage() + ");");
		}
		
		PageView<ArticleinfoDto> preView = pageView.previousView();
		PageView<ArticleinfoDto> nextView = pageView.nextView();
		
		Map<String, Object> returnJson = new HashMap<String, Object>();
		returnJson.put("result", SystemConstants.AJAX_SUCCESS);
		returnJson.put("pageView", pageView.encode());
		returnJson.put("firstPage", pageView.getFirstPage());
		returnJson.put("lastPage", pageView.getLastPage());
		returnJson.put("currentPage", pageNumber);
		returnJson.put("preView", preView==null? "":preView.encode());
		returnJson.put("nextView", nextView==null? "":nextView.encode());
		returnJson.put("list", convertArticleinfoListToPageData(pageView.getPageData(pageNumber) ) );

		return returnJson;
	}
	
	private List<Map<String, Object>> convertArticleinfoListToPageData(List<ArticleinfoDto> articleinfoList) {
		List<Map<String, Object>> jsonArray = new ArrayList<Map<String, Object>>(articleinfoList.size());
		for (ArticleinfoDto elem : articleinfoList) {
			Map<String, Object> jsonData = new HashMap<String, Object>();
			String articleIdStr = SystemTools.encrypt(String.valueOf(elem.getId()) );
			jsonData.put("articleId", articleIdStr);
			jsonData.put("articleTitle", elem.getTitle());
			jsonData.put("articleAuthorName", elem.getAuthor().getName());
			jsonData.put("articleAuthorLogoUrl", elem.getAuthor().getLogoUrl());
			jsonData.put("articleAuthorSex", elem.getAuthor().getSex().toString());
			jsonData.put("articleAuthorStatement", elem.getAuthor().getStatement());
			jsonData.put("articleSubmitDate", SystemTools.createShowTime(elem.getSubmitDate()));
			jsonData.put("articleTextSummary", elem.getTextSummary());
			jsonData.put("articleSummaryPictureUrl", elem.getSummaryPictureUrl());
			jsonData.put("articlePositionX", elem.getPositionInfo().getLongitude());
			jsonData.put("articlePositionY", elem.getPositionInfo().getLatitude());

			jsonArray.add(jsonData);
		}
		
		return jsonArray;
	}
	

	@RequestMapping("showArticleDetails")
	public String showArticleDetails(HttpServletRequest request) {
		String pageNumberStr = request.getParameter("pageNumber");
		String pgViewEncodeStr = request.getParameter("pgViewEncodeStr");
		String searchPatternStr = request.getParameter("searchPattern");
		
		String articleIdStr = assertNotEmpty(request.getParameter("id"));

		
		PageView<ArticleDetailMessageDto> pageView = isNullOrEmpty(pgViewEncodeStr) ? new PageView<ArticleDetailMessageDto>(SystemConstants.PAGE_VIEW_DATA_COUNT_PER_PAGE_FOR_ARTICLE_DETAIL) : PageView.decode(pgViewEncodeStr);
		int pageNumber = isNullOrEmpty(pageNumberStr) ? pageView.getFirstPage() : convertToInteger(pageNumberStr);
		
		Long articleId = convertToLongObj(SystemTools.decrypt(articleIdStr));
		
		SearchPattern searchPattern = isNullOrEmpty(searchPatternStr) ? SearchPattern.EARLY_FIRST : SearchPattern.getSearchPattern(searchPatternStr);
		
		pageView = articleService.getDetailMessagesOfArticle(articleId, searchPattern, pageView);
		
		if (pageNumber > pageView.getLastPage() || pageNumber < pageView.getFirstPage()) {
			throw new IllegalArgumentException("Page " + pageNumber + " is not allowd for current view (" + pageView.getFirstPage() + "-" + pageView.getLastPage() + ");");
		}
		
		PageView<ArticleDetailMessageDto> preView = pageView.previousView();
		PageView<ArticleDetailMessageDto> nextView = pageView.nextView();
		
		request.setAttribute("list", convertArticleDetailMessageListToPageData(pageView.getPageData(pageNumber) ) );
		request.setAttribute("pageView", pageView.encode());
		request.setAttribute("firstPage", pageView.getFirstPage());
		request.setAttribute("lastPage", pageView.getLastPage());
		request.setAttribute("currentPage", pageNumber);
		request.setAttribute("preView", preView==null? "":preView.encode());
		request.setAttribute("nextView", nextView==null? "":nextView.encode());

		if (pageView.getPageData(pageView.getFirstPage()).size() == 0 ) {
			String warnId = SystemTools.getUUIDString();
			logger.warn("WARN ID: " + warnId + " , no detail message found for the required article:" + articleId);
			request.setAttribute("message", "您查看的内容不存在，或已被删除！消息ID：" + warnId);
			return "error";
		}
		else {
			return "article_detail";
		}
		
	}
	
	private List<Map<String, Object>> convertArticleDetailMessageListToPageData(List<ArticleDetailMessageDto> messageList ) {
		List<Map<String, Object>> jsonArray = new ArrayList<Map<String, Object>>(messageList.size());
		for (ArticleDetailMessageDto elem : messageList) {
			Map<String, Object> jsonData = new HashMap<String, Object>();
			jsonData.put("messageId", SystemTools.encrypt(String.valueOf(elem.getId())) );
			jsonData.put("messageTitle", elem.getTitle());
			jsonData.put("messageAuthorName", elem.getAuthor().getName());
			jsonData.put("messageAuthorId", elem.getAuthor().getId());
			jsonData.put("messageAuthorLogoUrl", elem.getAuthor().getLogoUrl());
			jsonData.put("messageAuthorSex", elem.getAuthor().getSex().toString());
			jsonData.put("messageAuthorStatement", elem.getAuthor().getStatement());
			jsonData.put("messageType", elem.getType());
			jsonData.put("messageTypeString", elem.getType().toShowString());
			jsonData.put("messageSubmitDate", SystemTools.createShowTime(elem.getSubmitDate()));
			jsonData.put("messageTextSummary", elem.getTextSummary());
			jsonData.put("messageSummaryPictureUrl", elem.getSummaryPictureUrl());
			jsonData.put("messageContent", elem.getContent());
			jsonData.put("messagePositionX", elem.getPositionInfo().getLongitude());
			jsonData.put("messagePositionY", elem.getPositionInfo().getLatitude());
			jsonData.put("messagePositionInfoAddress", elem.getPositionInfo().getAddress());

			jsonArray.add(jsonData);
		}
		
		return jsonArray;
	}
	
	@RequestMapping("submitArticle")
	@ResponseBody
	public Map<String, Object> submitArticle(HttpServletRequest request) {
		String articleSummaryStr = assertNotEmpty(request.getParameter("articleSummary"));
		String articleContent = assertNotEmpty(request.getParameter("articleContent"));
		String titleStr = assertNotEmpty(request.getParameter("articleTitle"));
		String articleCatagoryStr = assertNotEmpty(request.getParameter("articleCatagory"));
		
		String mapXStr = assertNotEmpty(request.getParameter("mapX"));
		String mapYStr = assertNotEmpty(request.getParameter("mapY"));
		String mapAddrStr = assertNotEmpty(request.getParameter("mapAddr"));
		String mapProviderStr = assertNotEmpty(request.getParameter("mapProvider"));

		ArticleCatagory articleCatagory = ArticleCatagory.getArticleCatagory(articleCatagoryStr);
		
		Long articleID = ResourceManager.generateNumberID();
		
		UserinfoDto userInfo = (UserinfoDto) request.getSession().getAttribute(SystemConstants.LOGINUSER_SESSION_NAME);
		Long userId = (Long)userInfo.getUserId();
		String userName = userInfo.getUserNickname();
		String userLogoPath = userInfo.getUserHeadImagUrl();
		String userIp = request.getRemoteAddr();
		Sex sex = userInfo.getUserSex();
		String statement = userInfo.getStatement();
		
		ArticleDetailMessageDto mainMessage = new ArticleDetailMessageDto(ResourceManager.generateNumberID());
		
		mainMessage.setArticleId(articleID);
		mainMessage.setAuthor(new Author(userId) );
		mainMessage.getAuthor().setSex(sex);
		mainMessage.getAuthor().setIp(userIp);
		mainMessage.getAuthor().setLogoUrl(userLogoPath);
		mainMessage.getAuthor().setName(userName);
		mainMessage.getAuthor().setStatement(statement);
		
		mainMessage.setContent(articleContent);

		mainMessage.setPositionInfo(new PositionInfo() );
		mainMessage.getPositionInfo().setAddress(assertMaxLength(convertToHtmlCapableString(mapAddrStr), SystemConstants.LENGTH_LIMIT_POSITION_ADDR) );
		mainMessage.getPositionInfo().setLatitude(convertToDouble(mapYStr));
		mainMessage.getPositionInfo().setLongitude(convertToDouble(mapXStr));
		mainMessage.getPositionInfo().setMapProviderId(convertToInteger(mapProviderStr));
		
		mainMessage.setStatus(ContentStatus.NORMAL);
		mainMessage.setSubmitDate(new MyDateDTTM() );
		
		String snapshotImage = isUserMediaExist(SystemTools.getEmbedTagFromHtml(articleContent) ) ? request.getContextPath() + "/" + SystemConstants.SYSTEM_RESOURCE_PATH_PICTURE_MEDIA : getFirstUserImagePath(SystemTools.getImgTagFromHtml(articleContent), request.getContextPath() ) ;
		mainMessage.setSummaryPictureUrl(snapshotImage != null ? snapshotImage : SystemConstants.SYSTEM_RESOURCE_PATH_PICTURE_EMPTY );

		mainMessage.setTextSummary(assertMaxLength(articleSummaryStr, SystemConstants.LENGTH_LIMIT_ARTICLE_SUMMARY) );
		mainMessage.setTitle(assertMaxLength(convertToHtmlCapableString(titleStr), SystemConstants.LENGTH_LIMIT_ARTICLE_TITLE));
		mainMessage.setType(MessageType.MAIN);
		
	
		ArticleinfoDto article = new ArticleinfoDto(articleID);

		article.setAuthor(new Author(userId) );
		article.getAuthor().setSex(sex);
		article.getAuthor().setIp(userIp);
		article.getAuthor().setLogoUrl(userLogoPath);
		article.getAuthor().setName(userName);
		article.getAuthor().setStatement(statement);
		
		article.setPositionInfo(new PositionInfo());
		article.getPositionInfo().setAddress(mainMessage.getPositionInfo().getAddress());
		article.getPositionInfo().setLatitude(mainMessage.getPositionInfo().getLatitude());
		article.getPositionInfo().setLongitude(mainMessage.getPositionInfo().getLongitude());
		article.getPositionInfo().setMapProviderId(mainMessage.getPositionInfo().getMapProviderId());
		
		article.setStatus(ContentStatus.NORMAL);
		article.setSubmitDate(mainMessage.getSubmitDate() );
		article.setSummaryPictureUrl(mainMessage.getSummaryPictureUrl());
		article.setTextSummary(mainMessage.getTextSummary());
		article.setTitle(mainMessage.getTitle());
		article.setCatagory(articleCatagory);
		
		articleService.doSaveArticle(article, mainMessage);
		
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("result", SystemConstants.AJAX_SUCCESS);

		return result;
	}

	@RequestMapping("ajaxSubmitArticleReply")
	@ResponseBody
	public Map<String, Object> ajaxSubmitArticleReply(HttpServletRequest request) {
		String summaryStr = assertNotEmpty(request.getParameter("articleSummary"));
		String content = assertNotEmpty(request.getParameter("articleContent"));
		String articleIdStr = assertNotEmpty(request.getParameter("articleId"));
		String mapXStr = assertNotEmpty(request.getParameter("mapX"));
		String mapYStr = assertNotEmpty(request.getParameter("mapY"));
		String mapAddrStr = assertNotEmpty(request.getParameter("mapAddr"));
		String mapProviderStr = assertNotEmpty(request.getParameter("mapProvider"));
		String pageViewEncodeStr = assertNotEmpty(request.getParameter("pageViewEncodeStr"));
		
		String titleStr = assertNotNull(request.getParameter("articleTitle"));	
		
		UserinfoDto userInfo = (UserinfoDto) request.getSession().getAttribute(SystemConstants.LOGINUSER_SESSION_NAME);
		Long userId = (Long)userInfo.getUserId();
		String userName = userInfo.getUserNickname();
		String userLogoPath = userInfo.getUserHeadImagUrl();
		String userIp = request.getRemoteAddr();
		Sex sex = (Sex)userInfo.getUserSex();
		String statement = userInfo.getStatement();
		
		ArticleDetailMessageDto reply = new ArticleDetailMessageDto(ResourceManager.generateNumberID());

		
		reply.setArticleId(convertToLongObj(SystemTools.decrypt(articleIdStr)));
		reply.setAuthor(new Author(userId) );
		reply.getAuthor().setSex(sex);
		reply.getAuthor().setIp(userIp);
		reply.getAuthor().setLogoUrl(userLogoPath);
		reply.getAuthor().setName(userName);
		reply.getAuthor().setStatement(statement);
		
		reply.setContent(content);

		reply.setPositionInfo(new PositionInfo() );
		reply.getPositionInfo().setAddress(assertMaxLength(convertToHtmlCapableString(mapAddrStr), SystemConstants.LENGTH_LIMIT_POSITION_ADDR));
		reply.getPositionInfo().setLatitude(convertToDouble(mapYStr));
		reply.getPositionInfo().setLongitude(convertToDouble(mapXStr));
		reply.getPositionInfo().setMapProviderId(convertToInteger(mapProviderStr));
		
		reply.setStatus(ContentStatus.NORMAL);
		reply.setSubmitDate(new MyDateDTTM() );
		
		String snapshotImage = isUserMediaExist(SystemTools.getEmbedTagFromHtml(content) ) ? request.getContextPath() + "/" + SystemConstants.SYSTEM_RESOURCE_PATH_PICTURE_MEDIA : getFirstUserImagePath(SystemTools.getImgTagFromHtml(content), request.getContextPath() ) ;
		reply.setSummaryPictureUrl(snapshotImage != null ? snapshotImage : SystemConstants.SYSTEM_RESOURCE_PATH_PICTURE_EMPTY );
		reply.setTextSummary(assertMaxLength(summaryStr, SystemConstants.LENGTH_LIMIT_ARTICLE_SUMMARY));
		reply.setTitle(assertMaxLength(convertToHtmlCapableString(titleStr), SystemConstants.LENGTH_LIMIT_ARTICLE_TITLE));
		reply.setType(MessageType.NORMAL);
		
		PageView oriPageView = PageView.decode(pageViewEncodeStr);	
		
		articleService.doSaveReply(reply, oriPageView);
		
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("result", SystemConstants.AJAX_SUCCESS);

		return result;
	}
	
	@RequestMapping("ajaxModifyArticleMessage")
	@ResponseBody
	public Map<String, Object> ajaxModifyArticleMessage(HttpServletRequest request) {
		String summaryStr = assertNotEmpty(request.getParameter("articleSummary"));
		String content = assertNotEmpty(request.getParameter("articleContent"));
		String messageIdStr = assertNotEmpty(request.getParameter("messageId"));
		String pageViewEncodeStr = assertNotEmpty(request.getParameter("pageViewEncodeStr"));
		
		String titleStr = assertNotNull(request.getParameter("articleTitle"));
		
		Long messageId = convertToLongObj(SystemTools.decrypt(messageIdStr));
		String snapshotImage = isUserMediaExist(SystemTools.getEmbedTagFromHtml(content) ) ? request.getContextPath() + "/" + SystemConstants.SYSTEM_RESOURCE_PATH_PICTURE_MEDIA : getFirstUserImagePath(SystemTools.getImgTagFromHtml(content), request.getContextPath() ) ;
		String summaryPicUrl = snapshotImage != null ? snapshotImage : SystemConstants.SYSTEM_RESOURCE_PATH_PICTURE_EMPTY;
		
		String summary = assertMaxLength(summaryStr, SystemConstants.LENGTH_LIMIT_ARTICLE_SUMMARY);
		String title = assertMaxLength(convertToHtmlCapableString(titleStr), SystemConstants.LENGTH_LIMIT_ARTICLE_TITLE);
		
		UserinfoDto userInfo = (UserinfoDto) request.getSession().getAttribute(SystemConstants.LOGINUSER_SESSION_NAME);
		Long userId = (Long)userInfo.getUserId();
		String userIp = request.getRemoteAddr();
		
		PageView oriPageView = PageView.decode(pageViewEncodeStr);	
		
		articleService.doChangeMessage(messageId, summary, summaryPicUrl, content, title, new MyDateDTTM(),userIp, userId, oriPageView);
		
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("result", SystemConstants.AJAX_SUCCESS);

		return result;
	}
	
	@RequestMapping("selectMessage")
	@ResponseBody
	public Map<String, Object> selectMessage(HttpServletRequest request) {
		String messageIdStr = assertNotEmpty(request.getParameter("messageId"));
		Long messageId = convertToLongObj(SystemTools.decrypt(messageIdStr));
		
		ArticleDetailMessageDto message = articleService.getDetailMessage(messageId);
		
		Map<String, Object> jsonData = new HashMap<String, Object>();
		jsonData.put("messageContent", message.getContent());
		jsonData.put("messageTitle", message.getTitle());
		jsonData.put("messagePositionInfoAddress", message.getPositionInfo().getAddress());
		
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("result", SystemConstants.AJAX_SUCCESS);
		result.put("obj", jsonData);

		return result;
	}
	
	@RequestMapping("deleteMessage")
	@ResponseBody
	public Map<String, Object> deleteMessage(HttpServletRequest request) {
		String messageIdStr = assertNotEmpty(request.getParameter("messageId"));
		String pageViewEncodeStr = assertNotEmpty(request.getParameter("pageViewEncodeStr"));
		
		Long messageId = convertToLongObj(SystemTools.decrypt(messageIdStr));
		
		UserinfoDto userInfo = (UserinfoDto) request.getSession().getAttribute(SystemConstants.LOGINUSER_SESSION_NAME);
		Long userId = (Long)userInfo.getUserId();
		
		PageView oriPageView = PageView.decode(pageViewEncodeStr);
		
		boolean isMainArticleDeleted = articleService.doDeleteMessage(messageId, userId, oriPageView);
		
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("result", SystemConstants.AJAX_SUCCESS);
		result.put("isMainArticleDeleted", isMainArticleDeleted);

		return result;
	}
	
	
	private String getFirstUserImagePath(List<String> imagePathList, String servletContext) {
		for (String elem : imagePathList) {
			if (!elem.contains(servletContext + "/" + SystemConstants.SYSTEM_RESOURCE_PATH_BASE) ) {
				return elem;
			}
		}
		
		return null;
	}
	
	private boolean isUserMediaExist(List<Map<String,String>> embedTagList) {
		return embedTagList.size() > 0 ? true : false;
	}

}
